 public override SearchResultSet GetSearchResults(int pageIndex, int pageSize, int userID, string[] forumsToSearch, string[] usersToSearch, string[] andTerms, string[] orTerms) {
//            bool likeMatch = false;
            bool hasORterms = false;
            string searchSQL = "SELECT DISTINCT B0.PostID, B0.ForumID, Weight = ({0}), P.PostDate FROM {1}, forums_Posts P WHERE {2} {3} AND {4} ORDER BY Weight DESC, PostDate DESC";
            string recordCount = "SELECT TotalRecords = COUNT(DISTINCT B0.PostID) FROM {1}, forums_Posts P WHERE {2} {3} AND {4}";
            string orSQL = "(";
            string[] clauses = new string[5];

			// ޸Ĳѯ by venjiang ֲѯЧʲ,о
			// OR clause in search terms
			//
			string likeBegin=" LIKE '%";
			string likeEnd="%' ";

			if (orTerms.Length > 1) 
			{
				hasORterms = true;

				for (int i = 0; i < orTerms.Length; i++) 
				{
					string barrel = "B0.Word " + likeBegin +  "{0}"+likeEnd;

					orSQL += string.Format(barrel, orTerms[i]);

					if ((i+1) < orTerms.Length) 
					{
						orSQL += " OR ";
					} 
					else 
					{
						clauses[2] += orSQL += ") AND ";
					}

				}
			}

			// AND clause in search terms
			//
			if (andTerms.Length > 0) 
			{

				for (int i = 0; i < andTerms.Length; i++) 
				{
					string barrel = "B{0}";

					// Build the clauses
					if (hasORterms)
						clauses[2] += string.Format(barrel, (i+1)) + ".Word " + likeBegin + andTerms[i] + likeEnd;
					else
						clauses[2] += string.Format(barrel, i) + ".Word  " + likeBegin + andTerms[i] + likeEnd;

					if ((i+1) < andTerms.Length) 
					{
						clauses[2] += " AND ";
					}

				}

				clauses[2] += " AND ";
			}



//            // OR clause in search terms
//            //
//            if (orTerms.Length > 1) {
//                hasORterms = true;
//
//                for (int i = 0; i < orTerms.Length; i++) {
//                    string barrel = "B0.WordHash = {0}";
//
//                    orSQL += string.Format(barrel, orTerms[i]);
//
//                    if ((i+1) < orTerms.Length) {
//                        orSQL += " OR ";
//                    } else {
//                        clauses[2] += orSQL += ") AND ";
//                    }
//
//                }
//            }
//
//            // AND clause in search terms
//            //
//            if (andTerms.Length > 0) {
//
//                for (int i = 0; i < andTerms.Length; i++) {
//                    string barrel = "B{0}";
//
//                    // Build the clauses
//                    if (hasORterms)
//                        clauses[2] += string.Format(barrel, (i+1)) + ".WordHash = " + andTerms[i];
//                    else
//                        clauses[2] += string.Format(barrel, i) + ".WordHash = " + andTerms[i];
//
//                    if ((i+1) < andTerms.Length) {
//                        clauses[2] += " AND ";
//                    }
//
//                }
//
//                clauses[2] += " AND ";
//            }

            // FORUMS
            //
            if (forumsToSearch.Length > 0) 
			{
                for (int i = 0; i < forumsToSearch.Length; i++) {
                    string barrel = "B0.ForumID = ";

                    // Build the clauses
                    clauses[4] += barrel + forumsToSearch[i];

                    if ((i+1) < forumsToSearch.Length) {
                        clauses[4] += " OR ";
                    } else {
                        clauses[4] = "(" + clauses[4] + ")";
                    }

                }
            }

            // Users
            //
            if (usersToSearch != null) {
                string usersSearch = string.Empty;

                for (int i = 0; i < usersToSearch.Length; i++) {
                    string barrel = "P.UserID = ";

                    // Build the clauses
                    usersSearch += barrel + usersToSearch[i];

                    if ((i+1) < usersToSearch.Length) {
                        usersSearch += " OR ";
                    } else {
                        usersSearch = " AND (" + usersSearch + ") ";
                    }

                }

                clauses[4] += usersSearch;
            }

            // Main Loop for AND clause in search terms
            //
            int loopCount = andTerms.Length;

            if (hasORterms)
                loopCount ++;

            if (loopCount > 0) {
                for (int i = 0; i < loopCount; i++) {
                    string barrel = "B{0}";

                    clauses[0] += string.Format(barrel, i) + ".Weight";
                    clauses[1] += "forums_SearchBarrel " + string.Format(barrel, i);
                    clauses[3] += string.Format(barrel, i) + ".PostID = P.PostID";

                    if ((i+1) < loopCount) {
                        clauses[0] += " + ";
                        clauses[1] += ", ";
                        clauses[3] += " AND ";
                    }
                }
            } else {
                clauses[0] = "0";
                clauses[1] = "forums_SearchBarrel B0";
                clauses[3] = "B0.PostID = P.PostID";
            }


            searchSQL = string.Format(searchSQL, clauses);

//			HttpContext.Current.Response.Write(searchSQL);
//			HttpContext.Current.Response.End();

            recordCount = string.Format(recordCount, clauses);

            SearchResultSet result = new SearchResultSet();
            DateTime searchDuration;
			using( SqlConnection connection = GetSqlConnection() ) {
				SqlCommand command = new SqlCommand("forums_Search", connection);
				SqlDataReader reader;

				// Mark as stored procedure
				command.CommandType = CommandType.StoredProcedure;

				// Add parameters
				command.Parameters.Add("@SearchSQL", SqlDbType.NVarChar, 4000).Value = searchSQL;
				command.Parameters.Add("@RecordCountSQL", SqlDbType.NVarChar, 4000).Value = recordCount;
				command.Parameters.Add("@PageIndex", SqlDbType.Int).Value = pageIndex;
				command.Parameters.Add("@PageSize", SqlDbType.Int).Value = pageSize;

				connection.Open();
				reader = command.ExecuteReader();

				// Process first record set 
				//
				while (reader.Read()) {
					Post p;

					p = PopulatePostFromIDataReader(reader);

					result.Posts.Add(p);

				}

				// Move to the next result
				//
				if (reader.NextResult()) {
					reader.Read();
					result.TotalRecords = Convert.ToInt32(reader[0]);
				}

				// Get the duration of the search?
				//
				if (reader.NextResult()) {
					reader.Read();

					searchDuration = (DateTime) reader["Duration"];

					// Calculate the number of seconds it took the search to execute
					//
					int ms = Convert.ToInt32(searchDuration.ToString("ff"));
					result.SearchDuration = (double) ms / 1000;
				}

				connection.Close();

				return result;
			}
        }
